/*
Author:
	Kaloyan Ivanov, <kaloyan.ivanov@gmail.com>

License:
	New BSD License

Class
	_MOOXY_GALLERY
	
Requires:
	mootools 1.2 core
	mootools 1.2 more
*/


var _MOOXY_GALLERY = new Class({

	initialize: function(options) {
		// general settings
		this.gallery	=	$(options.GID);
		
		this.slideshow_interval 	= 	options.slideshow_interval || 5;
		this.keyboard_navigation 	= 	options.keyboard_navigation || true;
		this.slideshow_autostart 	= 	options.slideshow_autostart || false;
		this.scroll_speed 			= 	options.scroll_speed || 5;
		this.gallery_width			=	options.gallery_width;
		this.gallery_height			=	options.gallery_height;
		this.img_transitions_arr	=	options.img_transitions_arr || ['fadeIn'];

		this.thumbs_box		=	$$('#' + options.GID + ' .mooxy_thumbs')[0];
		this.image			=	$$('#' + options.GID + ' .mooxy_image')[0];
		this.thumbarea		=	$$('#' + options.GID + ' .mooxy_thumbarea')[0];
		this.imagearea		=	$$('#' + options.GID + ' .mooxy_imagearea')[0];
		this.cache			=	$$('#' + options.GID + ' .mooxy_cache')[0];
		this.loader			=	$$('#' + options.GID + ' .mooxy_loader')[0];
		this.navigation		=	$$('#' + options.GID + ' .mooxy_navigation')[0];
		this.thumbs_array	=	this.thumbs_box.getElements('li');
		this.imgBase		=	options.GID + '_mooxy_img_';
		this.thumbBase		=	options.GID + '_mooxy_thumb_';

		// init gallery controls
		this.slideleft		=	$$('#' + options.GID + ' .mooxy_slideleft')[0];
		this.slideright		=	$$('#' + options.GID + ' .mooxy_slideright')[0];
		this.slideshowstart	=	$$('#' + options.GID + ' .mooxy_slideshowstart')[0];
		this.previmg		=	$$('#' + options.GID + ' .mooxy_previmg')[0];
		this.nextimg		=	$$('#' + options.GID + ' .mooxy_nextimg')[0];
		
		this.current_image		=	0;
		this.next_image			=	1;
		this.slideshow_timer;
		this.transition_timer;
		this.transition_obj		=	new Hash();
		this.slideshow_state	=	!this.slideshow_autostart;
		
		// gallery init...
		this.thumbarea.setStyle('width', this.gallery_width - 38); // scroll arrow * 2 = 26px + 12px margins
		this.imagearea.setStyle('width', this.gallery_width);
		this.imagearea.setStyle('height', this.gallery_height);

		this.thumbs_array.each(function(item, index) {
			var imgSrc = item.getElements('span')[0].innerHTML;
			item.addEvent('click', function() {thisItem.setimg(index, imgSrc);});
		});

		// load first image
		this.setimg(0, this.thumbs_array[0].getElements('span')[0].innerHTML);
		
		// add keyboard controls
		if(this.keyboard_navigation) {
			document.addEvent('keyup', function(event) {
						if(event.key == 'left') {this.img_change(0);}
						if(event.key == 'right') {this.img_change(1);}
					}.bind(this));  // mootools events binding magick :)
		}

		// Attach events...
		var thisItem = this;
		this.slideleft.addEvent('click', function(){thisItem.move_thumbs_l();});
		this.slideright.addEvent('click', function(){thisItem.move_thumbs_r();});
		this.slideshowstart.addEvent('click', function(){thisItem.slideshow();});
		this.previmg.addEvent('click', function(){thisItem.img_change(0);});
		this.nextimg.addEvent('click', function(){thisItem.img_change(1);});
		
		this.slideshow();
	},


	loadImage: function(source, id) {
		var newImage = new Asset.image(source, {id: id});
		newImage.store('isReady', false);
		newImage.addEvent('load', function() {this.store('isReady', true);})
		return newImage;
	},


	set_current_img: function(id) {
		// update active image's thumb
		$(this.thumbBase + this.current_image).getElement('img').set('class', 'mooxy_inactive-thumb');		
		$(this.thumbBase + id).getElement('img').set('class', 'mooxy_active-thumb');
		//TODO scroll to active thumb if it's nessesary
		
		
		this.current_image = id;
	},

	
	startTransition: function() {
		if(this.transition_obj.img.retrieve('isReady')) {
			clearInterval(this.transition_timer);
			this.loader.setStyle('display', 'none');
			this.img_scale(this.transition_obj.img);
			
			this.image.appendChild(this.transition_obj.img);
			this.img_transition(this.transition_obj.img, this.transition_obj.oldimg);  // change the image
		
			// preload {next} image
			this.preload_img(this.transition_obj.id);

			// update current image pointer
			this.set_current_img(this.transition_obj.id);
		} else {
			//TODO make "loadming..." visible
			this.loader.setStyle('display', 'block');
		}
	},


	cacheOldImage: function(img, oldimg) {
		if(oldimg.id != img.id) {
			var pImg = this.imagearea.getElement('img');
			if(pImg.id != oldimg.id) {
				this.cache.appendChild(pImg);
				var myFx = new Fx.Scroll(this.imagearea).set(0, 0);
			}
		}		
	},


	setimg: function(id, imgSrc) {
		thisItem = this;
		var img;
		clearInterval(this.transition_timer);
		if(!$(this.imgBase + id)) {
			img = this.loadImage(imgSrc, this.imgBase + id);
			this.cache.appendChild(img);
		} else {
			img = $(this.imgBase + id);
		}
		
		var oldimg = $(this.imgBase + this.current_image);
		
		// first remove old image if there is one
		this.cacheOldImage(img, oldimg);
		
		this.transition_obj = {img: img, oldimg: oldimg, id: id};
		//this.startTransition();

		this.transition_timer = setInterval('thisItem.startTransition()', 100);
	},
	

	calculate_next_img: function(id) {
		if(id >= this.current_image) {
			this.next_image = (id < (this.thumbs_array.length - 1))? id + 1 : 0;
		} else {
			this.next_image = (id === 0)? this.thumbs_array.length - 1 : id - 1;
		}
	},
	
	preload_img: function(id) {
		this.calculate_next_img(id);
		if(!$(this.imgBase + this.next_image)) {
			var imgSrc = this.thumbs_array[this.next_image].getElements('span')[0].innerHTML;
			var img = this.loadImage(imgSrc, {'id': this.imgBase + this.next_image});
			this.cache.appendChild(img);
		}
	},
	
	
	img_change: function(direction) {
		var idx = 0;	
		if(direction == 1) { // 1 is forward; 0 is backward
			idx = (this.current_image == (this.thumbs_array.length - 1))? 0 : this.current_image + 1;
		} else {
			idx = (this.current_image === 0)? this.thumbs_array.length - 1 : this.current_image - 1;
		}
		var url = this.thumbs_array[idx].getElements('span')[0].innerHTML;
		this.setimg(idx, url);
	},
	
	
	move_thumbs_l: function() {
		var to;
		var scr = this.thumbarea.getScroll().x;
		if(scr > 0) {
			if(scr > this.gallery_width) {
				to = scr - this.gallery_width;
			} else {
				to = 0;
			}

			var myFx = new Fx.Scroll(this.thumbarea, {
			    duration: 1300,
			    wait: false,
				transition: Fx.Transitions.Back.easeOut
			}).start(to, 0);
		}
	},
	
	move_thumbs_r: function() {
		var lastImg = this.thumbs_array.getLast();
		var ofset = lastImg.getPosition(this.thumbs_box).x + lastImg.getSize().x;
		var scr = this.thumbarea.getScroll().x;
		if((ofset - scr) > this.gallery_width) {

			var myFx = new Fx.Scroll(this.thumbarea, {
			    duration: 1300,
			    wait: false,
				transition: Fx.Transitions.Back.easeOut
			}).start((scr + this.gallery_width), 0);
		}
	},
	
	
	slideshow: function() {
		if(this.slideshow_state) {
			clearInterval(this.slideshow_timer);
			this.slideshowstart.setStyle('background', 'url(images/play.png) left center no-repeat');
		} else {
			this.slideshow_timer = setInterval('$$(\'#' + this.gallery.id + ' .mooxy_nextimg\')[0].fireEvent("click")',
			 									this.slideshow_interval * 1000);
			this.slideshowstart.setStyle('background', 'url(images/pause.png) left center no-repeat');
		}
		this.slideshow_state = !this.slideshow_state;
	},


	img_scale: function(img) {
		if(img.height > 0) {
			var ratio = img.height / img.width;

			if(img.width >= this.gallery_width) {
				img.width = this.gallery_width;
				img.height = img.width * ratio;
			}
			if(img.height >= this.gallery_height) {
				img.height = this.gallery_height;
				img.width = img.height / ratio;
			}

			//set margins
			var m; // calculated margin
			if(img.width < this.gallery_width) {
				m = (this.gallery_width - img.width) / 2;
				img.setStyle('margin-left', m);
				img.setStyle('margin-right', m);
			}

			if(img.height < this.gallery_height) {
				m = (this.gallery_height - img.height) / 2;
				img.setStyle('margin-top', m);
				img.setStyle('margin-bottom', m);
			}
		}
	},
	
	
	clear_old_img: function(img, oldimg) {
		if(img.id !== oldimg.id) {
			this.cache.appendChild(oldimg);
			var myFx = new Fx.Scroll(this.imagearea).set(0, 0);
		}
		this.navigation.setStyle('display', 'inline');
	},
	

	img_transition: function(img, oldimg) {
		var transition = this.img_transitions_arr.getRandom();
		//var  transition = 'fadeIn';
		//var  transition = 'bounceOut';
		//var  transition = 'backEaseOut';
		//var  transition = 'scroll';
		var myFx;
		var thisItem = this;

		switch(transition) {

			case 'fadeIn':
				oldimg.set('opacity', '0');
				img.set('opacity', 0);
				this.navigation.setStyle('display', 'none');
				myFx = new Fx.Scroll(this.imagearea, {duration:1}).toElement(img);
				this.clear_old_img(img, oldimg)
				img.tween('opacity', 0, 1);
				break;

			case 'bounceOut':
				img.set('opacity', 1);
				this.navigation.setStyle('display', 'none');
				myFx = new Fx.Scroll(this.imagearea, {duration: 1000,
									wait: false, transition: Fx.Transitions.Bounce.easeOut,
									onComplete: function(){ thisItem.clear_old_img(img, oldimg) }
											}).toElement(img);
				break;
				
			case 'backEaseOut':  // FIXME doesn't work
				img.set('opacity', 1);
				this.navigation.setStyle('display', 'none');
				myFx = new Fx.Scroll(this.imagearea, {duration: 1000,
									wait: false, transition: Fx.Transitions.Back.easeOut,
									onComplete: function(){ thisItem.clear_old_img(img, oldimg) }
											}).toElement(img);
				break;
			
			case 'scroll':
				img.set('opacity', 1);
				this.navigation.setStyle('display', 'none');
				myFx = new Fx.Scroll(this.imagearea, {duration: 600, wait: false, 
									onComplete: function(){ thisItem.clear_old_img(img, oldimg) }
													}).toElement(img);
				break;
		}

	}

});  // end of _MOOXY_GALLERY
